package com.sc.nft.entity.dto;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.Maps;
import com.sc.nft.entity.DigitalCollectionProductInfoCondition;
import com.sc.nft.entity.DigitalCollectionProductInfoFreeSubscribe;
import com.sc.nft.entity.DigitalCollectionProductInfoSubscribe;
import com.sc.nft.entity.vo.MyCollectionCountVO;
import com.sc.nft.enums.ProductInfoSubscribeEnum;
import com.sc.nft.exception.GlobalRunTimeException;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
@Data
public class ConfirmExchangeSubscribeDTO {
    @NotNull(message = "商品id不能为空")
    @ApiModelProperty("商品id")
    private Long productId;

    @NotNull(message = "兑换数量不能为空")
    @ApiModelProperty("兑换数量")
    private Integer quantity;

    @ApiModelProperty("已经兑换的商品数量")
    @JsonIgnore
    private Integer redeemedQuantity;

    @ApiModelProperty(value = "兑换条件主要信息")
    @JsonIgnore
    private DigitalCollectionProductInfoSubscribe digitalCollectionProductInfoSubscribe;

    @ApiModelProperty(value = "免费兑换条件的所需要持有藏品的id")
    @JsonIgnore
    private List<Long> freeCollectionIds;

    @ApiModelProperty("申购条件真实性,有一些可能数据以外删除导致条件不存在.所以要判定他是否真的存在")
    @JsonIgnore
    private Boolean subscribeConditionAuthentic = false;

    @ApiModelProperty("申购条件真实性,有一些可能数据以外删除导致条件不存在.所以要判定他是否真的存在")
    @JsonIgnore
    private Boolean freeConditionAuthentic = false;

    @JsonIgnore
    @ApiModelProperty("免费的最大申购码,这个是未经过加工的 没有减去已经获取的免费申购码数量.")
    private Integer maxFreeSubscribeNum = 0;

    @ApiModelProperty("免费兑换条件")
    @JsonIgnore
    private List<DigitalCollectionProductInfoFreeSubscribe> digitalCollectionProductInfoFreeSubscribes;

    @ApiModelProperty("条件所需要的藏品id集合")
    @JsonIgnore
    private List<Long> conditionCollectionIds;

    @ApiModelProperty(value = "申购条件")
    @JsonIgnore
    private List<DigitalCollectionProductInfoCondition> digitalCollectionProductInfoConditionList;

    @ApiModelProperty("用户已经申请的免费申购码数量")
    @JsonIgnore
    private Integer freeSubscribeNum = 0;

    @ApiModelProperty("最大兑换数量")
    @JsonIgnore
    private Integer maxSubscribeNum = 0;

    public void setDigitalCollectionProductInfoFreeSubscribes(List<DigitalCollectionProductInfoFreeSubscribe> digitalCollectionProductInfoFreeSubscribes) {
        if (Objects.nonNull(digitalCollectionProductInfoFreeSubscribes) && digitalCollectionProductInfoFreeSubscribes.size() > 0) {
            List<Long> collectionIdList = digitalCollectionProductInfoFreeSubscribes.stream()
                    .filter(collection -> Objects.nonNull(collection.getCollectionId()))
                    .map(DigitalCollectionProductInfoFreeSubscribe::getCollectionId)
                    .distinct()
                    .collect(Collectors.toList());
            this.freeCollectionIds = collectionIdList;
            if (CollUtil.isNotEmpty(collectionIdList)) {
                this.freeConditionAuthentic = true;
            }
        }
        this.digitalCollectionProductInfoFreeSubscribes = digitalCollectionProductInfoFreeSubscribes;
    }

    public void setConditionCollectionIds(List<Long> conditionCollectionIds) {
        this.conditionCollectionIds = conditionCollectionIds;
    }

    public void setDigitalCollectionProductInfoConditionList(List<DigitalCollectionProductInfoCondition> digitalCollectionProductInfoConditionList) {
        if (Objects.nonNull(digitalCollectionProductInfoConditionList) && digitalCollectionProductInfoConditionList.size() > 0) {
            this.subscribeConditionAuthentic = true;
        }
        this.conditionCollectionIds = digitalCollectionProductInfoConditionList.stream().filter(condition -> Objects.nonNull(condition.getCollectionId())).map(DigitalCollectionProductInfoCondition::getCollectionId).distinct().collect(Collectors.toList());
        this.digitalCollectionProductInfoConditionList = digitalCollectionProductInfoConditionList;
    }

    public void setRedeemedQuantity(Integer redeemedQuantity) {
        this.redeemedQuantity = redeemedQuantity;
    }


    public void subscribeTimeDecide() {
        DateTime now = DateTime.now();
        if (now.isBefore(digitalCollectionProductInfoSubscribe.getSubscribeStartTime())) {
            throw new GlobalRunTimeException("申购活动未开始");
        }
        if (now.isAfter(digitalCollectionProductInfoSubscribe.getSubscribeEndTime())) {
            throw new GlobalRunTimeException("申购活动已结束");
        }
    }
    public void conditionVerifyHook(List<MyCollectionCountVO> userCollectionList) {
        Map<Long, MyCollectionCountVO> userCollectionMap = (Objects.nonNull(userCollectionList) && userCollectionList.size() > 0)
                ? userCollectionList.stream().collect(Collectors.toMap(MyCollectionCountVO::getCollectionId, Function.identity()))
                : Maps.newHashMap();
        if (digitalCollectionProductInfoSubscribe.getConditionType() == ProductInfoSubscribeEnum.ALL) {
            if (digitalCollectionProductInfoConditionList.stream().anyMatch(condition -> Objects.isNull(userCollectionMap.get(condition.getCollectionId())))) {
                throw new GlobalRunTimeException("不满足申购参与条件");
            }
        } else if (digitalCollectionProductInfoSubscribe.getConditionType() == ProductInfoSubscribeEnum.OR) {
            if (!digitalCollectionProductInfoConditionList.stream().anyMatch(contion -> Objects.nonNull(userCollectionMap.get(contion.getCollectionId())))) {
                throw new GlobalRunTimeException("不满足申购参与条件");
            }
        }
    }


    public void maxFreeSubscribeNUmAdd(List<MyCollectionCountVO> userCollectionList) {
        // 把数据转换为Map以及对象的形式
        Map<Long, MyCollectionCountVO> userCollectionMap = (Objects.nonNull(userCollectionList) && userCollectionList.size() > 0)
                ? userCollectionList.stream().collect(Collectors.toMap(MyCollectionCountVO::getCollectionId, Function.identity()))
                : Maps.newHashMap();
        //
        for (DigitalCollectionProductInfoFreeSubscribe digitalCollectionProductInfoFreeSubscribe : digitalCollectionProductInfoFreeSubscribes) {
            if (Objects.isNull(digitalCollectionProductInfoFreeSubscribe.getCollectionId())
                    || digitalCollectionProductInfoFreeSubscribe.getCollectionId() <= 0) {
                this.maxFreeSubscribeNum = this.maxFreeSubscribeNum + digitalCollectionProductInfoFreeSubscribe.getQuantity();
            } else if (Objects.nonNull(userCollectionMap.get(digitalCollectionProductInfoFreeSubscribe.getCollectionId()))) {
                this.maxFreeSubscribeNum = this.maxFreeSubscribeNum + digitalCollectionProductInfoFreeSubscribe.getQuantity() * (userCollectionMap.get(digitalCollectionProductInfoFreeSubscribe.getCollectionId()).getCount());
            }
//            this.maxFreeSubscribeNum = this.maxFreeSubscribeNum - this.redeemedQuantity;
        }
        // 可以获取最大的数量-已经获取的数量
        Integer truthFreeSubscribe=this.maxFreeSubscribeNum-this.freeSubscribeNum;
        this.maxFreeSubscribeNum=truthFreeSubscribe>0?truthFreeSubscribe:0;
    }

    /**
     * 校验是否超过最大兑换数量
     */
    public void validateMaxSubscribeNum() {
        if(this.quantity + this.redeemedQuantity > this.maxSubscribeNum) {
            throw new GlobalRunTimeException("已超过最大兑换数量");
        }
    }

}
